# frozen_string_literal: true

require "rails_helper"

RSpec.describe NoticesController, type: :controller do
  it_requires_authentication for: {locate: :get}

  let(:notice) { create(:notice) }

  let(:xml) { Rails.root.join("spec/fixtures/hoptoad_test_notice.xml").read }

  let(:app) { create(:app) }

  let(:error_report) { double(valid?: true, generate_notice!: true, notice: notice, should_keep?: true) }

  context "notices API" do
    context "with bogus xml" do
      it "returns an error" do
        post :create, body: "<r><b>notxml</r>", format: :xml
        expect(response).to have_http_status(:unprocessable_content)
        expect(response.body).to eq("The provided XML was not well-formed")
      end
    end

    context "with all params" do
      before do
        expect(ErrorReport).to receive(:new).with(xml).and_return(error_report)
      end

      context "with xml pass in raw_port" do
        before do
          post :create, body: xml, format: :xml
        end

        it "generates a notice from raw xml [POST]" do
          expect(response).to be_successful
          # Same RegExp from Airbrake::Sender#send_to_airbrake (https://github.com/airbrake/airbrake/blob/master/lib/airbrake/sender.rb#L53)
          # Inspired by https://github.com/airbrake/airbrake/blob/master/test/sender_test.rb
          expect(response.body).to match(%r{<id[^>]*>#{notice.id}</id>})
          expect(response.body).to match(%r{<url[^>]*>(.+)#{locate_path(notice.id)}</url>})
        end
      end

      it "generates a notice from xml in a data param [POST]" do
        post :create, params: {data: xml, format: :xml}
        expect(response).to be_successful
        # Same RegExp from Airbrake::Sender#send_to_airbrake (https://github.com/airbrake/airbrake/blob/master/lib/airbrake/sender.rb#L53)
        # Inspired by https://github.com/airbrake/airbrake/blob/master/test/sender_test.rb
        expect(response.body).to match(%r{<id[^>]*>#{notice.id}</id>})
        expect(response.body).to match(%r{<url[^>]*>(.+)#{locate_path(notice.id)}</url>})
      end

      it "generates a notice from xml [GET]" do
        get :create, params: {data: xml, format: :xml}
        expect(response).to be_successful
        expect(response.body).to match(%r{<id[^>]*>#{notice.id}</id>})
        expect(response.body).to match(%r{<url[^>]*>(.+)#{locate_path(notice.id)}</url>})
      end
      context "with an invalid API_KEY" do
        let(:error_report) { double(valid?: false) }

        it "return 422" do
          post :create, params: {format: :xml, data: xml}
          expect(response).to have_http_status(:unprocessable_content)
        end
      end
    end

    context "without params needed" do
      it "return 400" do
        post :create, format: :xml
        expect(response).to have_http_status(:bad_request)
        expect(response.body).to eq("Need a data params in GET or raw post data")
      end
    end
  end

  describe "GET /locate/:id" do
    context "when logged in as an admin" do
      before do
        @user = create(:user, admin: true)
        sign_in @user
      end

      it "should locate notice and redirect to problem" do
        problem = create(:problem, app: app, environment: "production")
        err = create(:err, problem: problem)
        notice = create(:notice, err: err)
        get :locate, params: {id: notice.id}
        expect(response).to redirect_to(app_problem_path(problem.app, problem))
      end
    end
  end

  describe "GET /notices/:id" do
    context "when logged in as an admin" do
      before do
        @user = create(:user, admin: true)
        sign_in @user
      end

      it "should locate notice and redirect to problem with notice_id" do
        problem = create(:problem, app: app, environment: "production")
        err = create(:err, problem: problem)
        notice = create(:notice, err: err)
        get :show_by_id, params: {id: notice.id}
        expect(response).to redirect_to(app_problem_path(problem.app, problem, notice_id: notice.id))
      end
    end
  end
end
